"""
答案质量检查器
负责评估生成答案的质量和相关性
"""

import re
import logging
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from enum import Enum

from ..utils.logger import setup_logger


class QualityLevel(Enum):
    """质量等级枚举"""
    HIGH = "high"  # 高质量
    MEDIUM = "medium"  # 中等质量
    LOW = "low"  # 低质量
    POOR = "poor"  # 质量很差


@dataclass
class QualityResult:
    """质量检查结果"""
    level: QualityLevel
    score: float
    issues: List[str]
    suggestions: List[str]
    is_relevant: bool


class QualityChecker:
    """答案质量检查器"""
    
    def __init__(self):
        """初始化质量检查器"""
        self.logger = setup_logger(__name__)
        
        # 低质量指标
        self.poor_quality_indicators = [
            "抱歉", "无法", "没有找到", "未找到", "不知道", "不清楚",
            "无法提供", "无法回答", "抱歉，我", "很抱歉",
            "没有相关信息", "信息不足", "无法确定"
        ]
        
        # 高质量指标
        self.high_quality_indicators = [
            "详细", "具体", "准确", "推荐", "建议", "路线", "时间",
            "距离", "费用", "开放时间", "地址", "电话", "特色"
        ]
        
        # 相关性关键词
        self.relevance_keywords = [
            "成都", "贵阳", "北京", "上海", "广州", "深圳", "杭州", "南京",
            "景点", "美食", "餐厅", "酒店", "交通", "路线", "导航",
            "大熊猫", "宽窄巷子", "锦里", "春熙路", "天府广场"
        ]
        
        self.logger.info("答案质量检查器初始化完成")
    
    def check_quality(self, query: str, answer: str, context: str = "") -> QualityResult:
        """
        检查答案质量
        
        Args:
            query: 用户查询
            answer: 生成的答案
            context: 检索到的上下文（可选）
            
        Returns:
            质量检查结果
        """
        try:
            self.logger.info(f"开始质量检查: 查询长度={len(query)}, 答案长度={len(answer)}")
            
            # 基础质量检查
            basic_score = self._check_basic_quality(answer)
            
            # 相关性检查
            relevance_score = self._check_relevance(query, answer, context)
            
            # 完整性检查
            completeness_score = self._check_completeness(query, answer)
            
            # 计算综合得分
            overall_score = (basic_score + relevance_score + completeness_score) / 3
            
            # 确定质量等级
            level = self._determine_quality_level(overall_score)
            
            # 识别问题
            issues = self._identify_issues(query, answer, overall_score)
            
            # 生成建议
            suggestions = self._generate_suggestions(issues, level)
            
            # 判断相关性
            is_relevant = relevance_score > 0.2
            
            result = QualityResult(
                level=level,
                score=overall_score,
                issues=issues,
                suggestions=suggestions,
                is_relevant=is_relevant
            )
            
            self.logger.info(f"质量检查完成: 等级={level.value}, 得分={overall_score:.2f}, 相关性={is_relevant}")
            return result
            
        except Exception as e:
            self.logger.error(f"质量检查失败: {e}")
            return QualityResult(
                level=QualityLevel.POOR,
                score=0.0,
                issues=[f"质量检查过程出错: {str(e)}"],
                suggestions=["请重新尝试查询"],
                is_relevant=False
            )
    
    def _check_basic_quality(self, answer: str) -> float:
        """检查基础质量"""
        if not answer or len(answer.strip()) < 10:
            return 0.0
        
        score = 0.5  # 基础分
        
        # 检查长度
        if len(answer) > 50:
            score += 0.2
        
        # 检查是否包含低质量指标
        for indicator in self.poor_quality_indicators:
            if indicator in answer:
                score -= 0.3
                break
        
        # 检查是否包含高质量指标
        for indicator in self.high_quality_indicators:
            if indicator in answer:
                score += 0.1
        
        return max(0.0, min(1.0, score))
    
    def _check_relevance(self, query: str, answer: str, context: str = "") -> float:
        """检查相关性"""
        score = 0.0
        
        # 检查是否是澄清消息
        clarification_indicators = [
            "请提供", "需要", "缺失", "缺少", "为了为您", "请告诉", "请说明"
        ]
        is_clarification = any(indicator in answer for indicator in clarification_indicators)
        
        if is_clarification:
            # 澄清消息给予较高的相关性分数
            score = 0.8
            return score
        
        # 提取查询关键词
        query_keywords = self._extract_keywords(query)
        answer_keywords = self._extract_keywords(answer)
        
        # 计算关键词重叠度
        if query_keywords:
            overlap = len(set(query_keywords) & set(answer_keywords)) / len(query_keywords)
            score += overlap * 0.4
        
        # 检查是否包含相关性关键词
        relevance_count = 0
        for keyword in self.relevance_keywords:
            if keyword in query and keyword in answer:
                relevance_count += 1
        
        if relevance_count > 0:
            score += min(0.3, relevance_count * 0.1)
        
        # 检查上下文相关性
        if context:
            context_keywords = self._extract_keywords(context)
            if context_keywords:
                context_overlap = len(set(query_keywords) & set(context_keywords)) / len(query_keywords)
                score += context_overlap * 0.2
        
        # 如果答案包含查询中的主要词汇，给予额外分数
        query_words = set(query_keywords)
        answer_words = set(answer_keywords)
        if query_words and answer_words:
            # 检查是否有任何查询词汇在答案中出现
            if query_words & answer_words:
                score += 0.3
        
        return min(1.0, score)
    
    def _check_completeness(self, query: str, answer: str) -> float:
        """检查完整性"""
        score = 0.3  # 基础分
        
        # 检查是否回答了问题
        if "？" in query or "?" in query:
            if "。" in answer or "！" in answer or "!" in answer:
                score += 0.3
        
        # 检查信息丰富度
        if len(answer) > 100:
            score += 0.2
        
        if len(answer) > 200:
            score += 0.2
        
        return min(1.0, score)
    
    def _determine_quality_level(self, score: float) -> QualityLevel:
        """确定质量等级"""
        if score >= 0.8:
            return QualityLevel.HIGH
        elif score >= 0.6:
            return QualityLevel.MEDIUM
        elif score >= 0.4:
            return QualityLevel.LOW
        else:
            return QualityLevel.POOR
    
    def _identify_issues(self, query: str, answer: str, score: float) -> List[str]:
        """识别问题"""
        issues = []
        
        if score < 0.3:
            issues.append("答案质量很低")
        
        if len(answer) < 20:
            issues.append("答案过于简短")
        
        # 检查是否包含低质量指标
        for indicator in self.poor_quality_indicators:
            if indicator in answer:
                issues.append(f"包含低质量表述: {indicator}")
                break
        
        # 检查相关性
        query_keywords = self._extract_keywords(query)
        answer_keywords = self._extract_keywords(answer)
        
        if query_keywords:
            overlap = len(set(query_keywords) & set(answer_keywords))
            if overlap < len(query_keywords) * 0.3:
                issues.append("答案与查询相关性较低")
        
        return issues
    
    def _generate_suggestions(self, issues: List[str], level: QualityLevel) -> List[str]:
        """生成改进建议"""
        suggestions = []
        
        if level == QualityLevel.POOR:
            suggestions.append("建议重新查询或提供更具体的问题")
        
        if "答案过于简短" in issues:
            suggestions.append("建议提供更详细的信息")
        
        if "相关性较低" in issues:
            suggestions.append("建议使用更相关的关键词进行查询")
        
        if not suggestions:
            suggestions.append("答案质量良好")
        
        return suggestions
    
    def _extract_keywords(self, text: str) -> List[str]:
        """提取关键词"""
        # 简单的关键词提取
        words = re.findall(r'[\u4e00-\u9fff]+', text)
        
        # 对于长词，尝试分割成更短的词
        all_words = []
        for word in words:
            if len(word) <= 4:
                all_words.append(word)
            else:
                # 对于长词，尝试分割
                for i in range(len(word) - 1):
                    for j in range(i + 2, min(i + 5, len(word) + 1)):
                        all_words.append(word[i:j])
        
        # 去重并过滤
        unique_words = list(set(all_words))
        filtered_words = [word for word in unique_words if 2 <= len(word) <= 4]
        return filtered_words
    
    def should_reject_answer(self, quality_result: QualityResult) -> bool:
        """判断是否应该拒绝答案"""
        return (
            quality_result.level == QualityLevel.POOR or
            not quality_result.is_relevant or
            quality_result.score < 0.3
        )
    
    def get_rejection_message(self, quality_result: QualityResult) -> str:
        """获取拒绝答案的消息"""
        if not quality_result.is_relevant:
            return "抱歉，我目前无法为您提供相关的旅游建议。"
        
        if quality_result.level == QualityLevel.POOR:
            return "抱歉，我无法为您提供有效的帮助。"
        
        return "抱歉，我目前无法回答您的问题。"
